# @Author       : Xu Xiaokang
# @Email        :
# @Date         : 2025-08-28 21:08:12
# @LastEditors  : Xu Xiaokang
# @LastEditTime : 2025-08-29 23:49:13
# @Filename     :
# @Description  :

# source run_non_project.tcl
# Complete Non-Project Mode Script with Default Strategy Only

# 记录开始时间
set total_start_time [clock seconds]
set start_formatted_time [clock format $total_start_time -format "%Y-%m-%d %H:%M:%S"]

# 设置准确的源文件路径
set origin_dir "."
set output_dir [file join $origin_dir output]
# 创建输出目录
file mkdir $output_dir

#~ 设置参数
set prj_name "VCT"
set main_bd_name "Versal_CPM_Tandem_PCIe_DFX"
set top_module "Versal_CPM_Tandem_PCIe_top"
set part_name "xcvc1902-vsva2197-2MP-e-S"
set run_jobs 32

# 设置Vivado最大线程为32
set_param general.maxThreads 32

# 设置项目文件路径
set project_file [file normalize [file join $origin_dir ${prj_name}.xpr]]
set main_bd_path [file normalize [file join $origin_dir ${prj_name}.srcs sources_1 bd \
                    $main_bd_name $main_bd_name.bd]]

# 检查文件路径的有效性，无效则退出
if {![file exists $project_file]} {
    puts "ERROR: Project file does not exist: $project_file"
    return -code error "Project file not found"
}

if {![file exists $main_bd_path]} {
    puts "ERROR: Main BD file does not exist: $main_bd_path"
    return -code error "Main BD file not found"
}

puts "INFO: Project file found: $project_file"
puts "INFO: Main BD file found: $main_bd_path"


#++++++++++++++++++++++++++ project mode begin ++++++++++++++++++++++++++
# 输出工程模式开始信息
puts {
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
========================== project mode begin ==========================
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
}

set ooc_start_time [clock seconds]

puts "INFO: Starting OOC mode generation..."

# 打开主项目
open_project $project_file

#+++++++++++++++++++++++++ OOC begin +++++++++++++++++++++++++++++
# 复位工程
reset_project

# 1. 生成Block Design的所有输出目标 (Output Products)
# 这会生成HDL文件、约束文件、仿真文件等BD支撑数据:cite[1]
puts "INFO: Generating output products for the block design..."
generate_target all [get_files $main_bd_path]

# 2. 配置并导出IP缓存 (Configuring and exporting IP cache)
# 此操作有助于加速后续流程，确保IP状态最新:cite[7]
puts "INFO: Configuring and exporting IP cache..."
set ips_in_design [get_ips -of_objects [get_files $main_bd_path]]
foreach ip $ips_in_design {
    catch {
        config_ip_cache -export [get_ips -all $ip]
    }
}

# 3. 导出IP用户文件 (Export IP User Files)
# 将IP相关的文件导出到用户目录，便于仿真或其他工具使用
puts "INFO: Exporting IP user files..."
export_ip_user_files -of_objects [get_files $main_bd_path] -no_script -sync -force -quiet

# 4. 为BD中的IP创建独立的运行（run）(Create IP Runs)
# 这将为BD中的每个IP创建单独的“综合运行（synthesis run）”:cite[3]
puts "INFO: Creating IP runs for the block design..."
create_ip_run [get_files -of_objects [get_fileset sources_1] $main_bd_path]

# 5. 启动所有综合运行 (Launch Synthesis Runs)
# 使用多线程并行综合，显著加快构建速度（-jobs 参数可根据你的CPU核心数调整）:cite[4]
puts "INFO: Launching all synthesis runs with $run_jobs jobs..."
launch_runs [get_runs *_synth_1] -jobs $run_jobs

# 等待所有综合运行完成 (可选，如果需要等待综合完成再进行后续操作，可以取消注释下一行)
puts "INFO: Waiting for all synthesis runs to complete..."
wait_on_run [get_runs *_synth_1]

puts "INFO: Tcl script execution completed. Check the 'Design Runs' window for synthesis status."
#----------------------------- OOC end -----------------------------

# 获取所有工程文件, 包括v sv vhdl c文件等
# 获取并显示所有设计文件

# 获取所有HDL源文件 (Verilog, SystemVerilog, VHDL)
set hdl_files [get_files -of_objects [get_filesets sources_1] {*.v *.sv *.vhd *.vhdl}]
puts "Found [llength $hdl_files] HDL files:"
foreach file $hdl_files {
    puts "  $file"
}

# 获取所有IP核文件 (.xci)
set ip_files [get_files -of_objects [get_filesets sources_1] *.xci]
puts "\nFound [llength $ip_files] IP core files:"
foreach file $ip_files {
    puts "  $file"
}

# 获取所有Block Design文件 (.bd)
set bd_files [get_files -of_objects [get_filesets sources_1] *.bd]
puts "\nFound [llength $bd_files] Block Design files:"
foreach file $bd_files {
    puts "  $file"
}

# 获取所有约束文件 (.xdc)
set xdc_files [get_files -of_objects [get_filesets constrs_1] *.xdc]
puts "\nFound [llength $xdc_files] constraint files:"
foreach file $xdc_files {
    puts "  $file"
}

# 显示总计
set total_files [expr [llength $hdl_files] + [llength $ip_files] + [llength $bd_files] + [llength $xdc_files]]
puts "\nTotal design files found: $total_files"

# 关闭工程, 后续用Non-project模式
close_project

# 输出工程模式结束信息
puts {
----------------------------------------------------------------------
========================== project mode end ==========================
----------------------------------------------------------------------
}
set ooc_elapsed_time [expr [clock seconds] - $ooc_start_time]
puts "INFO: OOC generation completed in $ooc_elapsed_time seconds"
#------------------------------- project mode end ---------------------------


#++++++++++++++++++++++++++++++ read files begin +++++++++++++++++++++++++++++++
set read_file_start_time [clock seconds]

puts {
====================================
== PHASE 1: READING SOURCE FILES ==
====================================
}

###########################################################################
# 简化版：直接读取工程模式已生成的 BD 输出文件 + 其他文件
# 前提：工程模式下已执行 "Generate Output Products" 生成 BD 的综合文件
###########################################################################
###########################################################################
# 简化版：直接读取工程模式已生成的 BD 输出文件 + 其他文件
# 前提：工程模式下已执行 "Generate Output Products" 生成 BD 的综合文件
# 注意：输出信息用英文（避免 TCL 执行报错），注释保留中文便于理解
###########################################################################

# -------------------------- 1. read_bd：读取 BD 源文件（关联 IP 元数据） --------------------------
puts "\n2. Reading BD source files (.bd)..."
# BD 源文件路径（基于 origin_dir，绝对路径）
# set BD_SOURCE_FILES [list \
#     "${origin_dir}/VCT.srcs/sources_1/bd/bd_cntr16/bd_cntr16.bd" \
#     "${origin_dir}/VCT.srcs/sources_1/bd/bd_cntr8/bd_cntr8.bd" \
#     "${origin_dir}/VCT.srcs/sources_1/bd/bd_passthru/bd_passthru.bd" \
#     "${origin_dir}/VCT.srcs/sources_1/bd/bd_reverse/bd_reverse.bd" \
#     "${origin_dir}/VCT.srcs/sources_1/bd/Versal_CPM_Tandem_PCIe_DFX/Versal_CPM_Tandem_PCIe_DFX.bd"
# ]
set BD_SOURCE_FILES [list \
    "${origin_dir}/VCT.srcs/sources_1/bd/Versal_CPM_Tandem_PCIe_DFX/Versal_CPM_Tandem_PCIe_DFX.bd" \
    "${origin_dir}/VCT.srcs/sources_1/bd/bd_cntr16/bd_cntr16.bd" \
    "${origin_dir}/VCT.srcs/sources_1/bd/bd_cntr8/bd_cntr8.bd" \
    "${origin_dir}/VCT.srcs/sources_1/bd/bd_passthru/bd_passthru.bd" \
    "${origin_dir}/VCT.srcs/sources_1/bd/bd_reverse/bd_reverse.bd" \
]

# 批量 read_bd 并验证
foreach bd_src $BD_SOURCE_FILES {
    if {[file exists $bd_src]} {
        read_bd $bd_src
        puts "✅ Read BD source file: $bd_src"
    } else {
        puts "❌ BD source file not found! Path: $bd_src"
        exit 1
    }
}

# -------------------------- 2. 读取用户普通 HDL 文件 和 顶层文件 --------------------------
puts "\n==================== Reading user HDL files ===================="
set USER_HDL [list \
    "${origin_dir}/VCT.srcs/sources_1/imports/rtl/passthrough.v" \
    "${origin_dir}/VCT.srcs/sources_1/imports/rtl/reverse.v" \
    "${origin_dir}/VCT.srcs/sources_1/imports/cpm4/ST_c2h.sv" \
    "${origin_dir}/VCT.srcs/sources_1/imports/cpm4/ST_c2h_cmpt.sv" \
    "${origin_dir}/VCT.srcs/sources_1/imports/cpm4/ST_h2c.sv" \
    "${origin_dir}/VCT.srcs/sources_1/imports/cpm4/axi_st_module.sv" \
    "${origin_dir}/VCT.srcs/sources_1/imports/cpm4/axil_to_reg.sv" \
    "${origin_dir}/VCT.srcs/sources_1/imports/cpm4/desc_cnt.sv" \
    "${origin_dir}/VCT.srcs/sources_1/imports/cpm4/l3fwd_cntr.sv" \
    "${origin_dir}/VCT.srcs/sources_1/imports/cpm4/next_queue_fifo.sv" \
    "${origin_dir}/VCT.srcs/sources_1/imports/cpm4/perf_cntr.sv" \
    "${origin_dir}/VCT.srcs/sources_1/imports/cpm4/queue_cnts.sv" \
    "${origin_dir}/VCT.srcs/sources_1/imports/cpm4/user_control.sv" \
    "${origin_dir}/VCT.srcs/sources_1/imports/cpm4/Versal_CPM_Tandem_PCIe_top.sv"
]

read_verilog $USER_HDL
puts "✅ User HDL files read successfully (Total: [llength $USER_HDL])"

# -------------------------- 4. 读取约束文件（顺序无关，最后读） --------------------------
puts "\n==================== Reading constraint files ===================="
set XDC_FILES [list \
    "${origin_dir}/VCT.srcs/constrs_1/constrs/top.xdc" \
    "${origin_dir}/VCT.srcs/constrs_1/imports/bd/rpcntr_pblock.xdc" \
    "${origin_dir}/VCT.srcs/constrs_1/imports/rtl/rpwrdata_pblock.xdc" \
]

foreach xdc $XDC_FILES {
    if {[file exists $xdc]} {
        read_xdc $xdc
        puts "✅ Read constraint file: [file tail $xdc]"
    } else {
        puts "❌ Constraint file not found! Path: $xdc"
        exit 1
    }
}

set read_file_elapsed_time [expr [clock seconds] - $read_file_start_time]
puts "INFO: read_file completed in $read_file_elapsed_time seconds"
#------------------------------ read files end ------------------------------


#++ ==================== Synth begin ====================
set Synth_start_time [clock seconds]

# 明确设置顶层模块（使用变量）
set_property TOP $top_module [current_fileset]

puts {
===========================================
== PHASE 2: SYNTHESIS (Default Strategy) ==
===========================================
}

# 1.1 综合 - Synth Design (Default)
synth_design -top $top_module -part $part_name

# 1.1 Utilization - Synth Design (Default Report)
report_utilization -file ${output_dir}/Utilization_Synth_Design.rpt

# 1.2 Synthesis Report (由synth_design自动生成，在日志中查看)
puts "INFO: Synthesis Report generated in Vivado log"

write_checkpoint -force ${output_dir}/post_synth.dcp

set Synth_elapsed_time [expr [clock seconds] - $Synth_start_time]
puts "INFO: Synth completed in $Synth_elapsed_time seconds"
#-- ==================== Synth end ====================


#++ ==================== Impl begin ====================
set Impl_start_time [clock seconds]

puts {
================================================
== PHASE 3: IMPLEMENTATION (Default Strategy) ==
================================================
}

# 2.2 Opt Design (opt_design) (Default)
opt_design

# 2.2 DRC - Opt Design (Default Report)
report_drc -file ${output_dir}/DRC_Opt_Design.rpt

# 2.4 Place Design (place_design) (Default)
place_design

# 2.4 IO - Place Design (Default Report)
report_io -file ${output_dir}/IO_Place_Design.rpt

# 2.4 Utilization - Place Design (Default Report)
report_utilization -file ${output_dir}/Utilization_Place_Design.rpt

# 2.4 Control Sets - Place Design (Default Report)
report_control_sets -verbose -file ${output_dir}/Control_Sets_Place_Design.rpt

# 2.6 Post-Place Phys Opt Design (phys_opt_design) (Default)
phys_opt_design

# 2.7 Route Design (route_design) (Default)
route_design

# 2.7 DRC - Route Design (Default Report)
report_drc -file ${output_dir}/DRC_Route_Design.rpt

# 2.7 Methodology - Route Design (Default Report)
report_methodology -file ${output_dir}/Methodology_Route_Design.rpt

# 2.7 Power - Route Design (Default Report)
report_power -file ${output_dir}/Power_Route_Design.rpt

# 2.7 Route Status - Route Design (Default Report)
report_route_status -file ${output_dir}/Route_Status_Route_Design.rpt

# 2.7 Timing Summary - Route Design (Default Report)
report_timing_summary -max_paths 10 -report_unconstrained -file ${output_dir}/Timing_Summary_Route_Design.rpt

# 2.7 Clock Utilization - Route Design (Default Report)
report_clock_utilization -file ${output_dir}/Clock_Utilization_Route_Design.rpt

# 2.7 Bus Skew - Route Design (Default Report)
report_bus_skew -warn_on_violation -file ${output_dir}/Bus_Skew_Route_Design.rpt

# 2.7 implementation log (由route_design自动生成，在日志中查看)
puts "INFO: Implementation log generated in Vivado log"

write_checkpoint -force ${output_dir}/post_route.dcp

set Impl_elapsed_time [expr [clock seconds] - $Impl_start_time]
puts "INFO: Implementation completed in $Impl_elapsed_time seconds"
#-- ==================== Impl end ====================


#++ ==================== Bitstream begin ====================
# 降低 DRC 检查的严重级别（谨慎使用）
# set_property SEVERITY {Warning} [get_drc_checks NSTD-1]
# set_property SEVERITY {Warning} [get_drc_checks UCIO-1]

set Bitstream_start_time [clock seconds]

puts "=================================================="
puts "PHASE 4: BITSTREAM GENERATION (Default Strategy)"
puts "=================================================="

# 2.9 Write Bitstream (Default) - 使用变量命名bit文件
write_bitstream -force ${output_dir}/${top_module}.bit

# 2.9 implementation log (由write_bitstream自动生成，在日志中查看)
puts "INFO: Bitstream implementation log generated in Vivado log"

set Bitstream_elapsed_time [expr [clock seconds] - $Bitstream_start_time]
puts "INFO: Bitstream completed in $Bitstream_elapsed_time seconds"
#-- ==================== Bitstream end ====================


#+++++++++++++++++++++++++ 最后信息输出 ++++++++++++++++++++++++++
set reprot_info "\n==================================="
append reprot_info "\nCOMPLETED - DEFAULT STRATEGY ONLY"
append reprot_info "\n==================================="
append reprot_info "\nTop Module: $top_module"
append reprot_info "\nGenerated DEFAULT reports only:"
append reprot_info "\n"
append reprot_info "\nSYNTHESIS PHASE:"
append reprot_info "\n- Utilization_Synth_Design.rpt (Default)"
append reprot_info "\n- Synthesis Report (自动生成，查看日志)"
append reprot_info "\n"
append reprot_info "\nIMPLEMENTATION PHASE - Default Report:"
append reprot_info "\n- DRC_Opt_Design.rpt"
append reprot_info "\n- IO_Place_Design.rpt"
append reprot_info "\n- Utilization_Place_Design.rpt"
append reprot_info "\n- Control_Sets_Place_Design.rpt"
append reprot_info "\n- DRC_Route_Design.rpt"
append reprot_info "\n- Methodology_Route_Design.rpt"
append reprot_info "\n- Power_Route_Design.rpt"
append reprot_info "\n- Route_Status_Route_Design.rpt"
append reprot_info "\n- Timing_Summary_Route_Design.rpt"
append reprot_info "\n- Clock_Utilization_Route_Design.rpt"
append reprot_info "\n- Bus_Skew_Route_Design.rpt"
append reprot_info "\n"
append reprot_info "\nNON-DEFAULT REPORTS (注释掉，可按需启用):"
append reprot_info "\n# Timing_Summary_Design_Initialization.rpt"
append reprot_info "\n# Timing_Summary_Opt_Design.rpt"
append reprot_info "\n# Incremental_Reuse_Place_Design.rpt"
append reprot_info "\n# Timing_Summary_Place_Design.rpt"
append reprot_info "\n# Timing_Summary_Post_Place_Phys_Opt_Design.rpt"
append reprot_info "\n# Incremental_Reuse_Route_Design.rpt"
append reprot_info "\n# Timing_Summary_Post_Route_Phys_Opt_Design.rpt"
append reprot_info "\n# Bus_Skew_Post_Route_Phys_Opt_Design.rpt"
append reprot_info "\n"
append reprot_info "\nBITSTREAM PHASE:"
append reprot_info "\n- ${top_module}.bit (生成的bit文件)"
append reprot_info "\n- implementation log (自动生成，查看日志)"
append reprot_info "\n"
append reprot_info "\nTotal: 11个Default Report文件生成"
append reprot_info "\n8个非Default Report已注释，可按需取消注释使用"
append reprot_info "\n================================"
append reprot_info "\n=================== COMPLETE TIME SUMMARY ==================="
append reprot_info "\nCompilation started:             $start_formatted_time"

# 最后一次性输出所有内容
puts $reprot_info

# ==================== 完整时间统计 ====================
set total_elapsed [expr [clock seconds] - $total_start_time]

set output "\n=================== COMPLETE TIME SUMMARY ==================="
append output "\nthis project name: $prj_name"
append output "\nCompilation started:             $start_formatted_time"
append output "\nReading source files:            $read_file_elapsed_time seconds"
append output "\nSynthesis:                       $Synth_elapsed_time seconds"
append output "\nImplementation:                  $Impl_elapsed_time seconds"
append output "\nBitstream generation:            $Bitstream_elapsed_time seconds"
append output "\ntime total:                      [expr {
    $read_file_elapsed_time
    + $Synth_elapsed_time
    + $Impl_elapsed_time
    + $Bitstream_elapsed_time
}] seconds"
append output "\n=========================================================="
append output "\nTOTAL COMPILATION TIME:          $total_elapsed seconds"
append output "\n=========================================================="

puts $output
#--------------------------- 最后信息输出 ---------------------------
